<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>未来之窗——文章向量化工具</title>
    <style>
        :root {
            --primary-color: #2c3e50;
            --secondary-color: #3498db;
            --light-color: #ecf0f1;
            --dark-color: #34495e;
            --success-color: #2ecc71;
        }
        
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            line-height: 1.6;
            color: var(--primary-color);
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f9f9f9;
        }
        
        header {
            text-align: center;
            margin-bottom: 30px;
            padding-bottom: 20px;
            border-bottom: 2px solid var(--secondary-color);
        }
        
        h1 {
            color: var(--primary-color);
            margin-bottom: 10px;
        }
        
        .description {
            color: var(--dark-color);
            max-width: 800px;
            margin: 0 auto;
        }
        
        .container {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 30px;
        }
        
        @media (max-width: 768px) {
            .container {
                grid-template-columns: 1fr;
            }
        }
        
        .card {
            background: white;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        }
        
        h2 {
            color: var(--secondary-color);
            margin-bottom: 15px;
            padding-bottom: 8px;
            border-bottom: 1px solid var(--light-color);
        }
        
        textarea {
            width: 100%;
            min-height: 150px;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            margin-bottom: 15px;
            font-family: inherit;
            resize: vertical;
        }
        
        .controls {
            display: flex;
            gap: 10px;
            margin-bottom: 20px;
            flex-wrap: wrap;
        }
        
        button {
            background-color: var(--secondary-color);
            color: white;
            border: none;
            padding: 8px 16px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            transition: background-color 0.3s;
        }
        
        button:hover {
            background-color: #2980b9;
        }
        
        button.secondary {
            background-color: var(--dark-color);
        }
        
        button.secondary:hover {
            background-color: #2c3e50;
        }
        
        button.success {
            background-color: var(--success-color);
        }
        
        button.success:hover {
            background-color: #27ae60;
        }
        
        .word-input-group {
            display: flex;
            gap: 10px;
            margin-bottom: 15px;
        }
        
        #wordInput {
            flex: 1;
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
        }
        
        .result-section {
            margin-top: 20px;
        }
        
        .result-section h3 {
            margin-bottom: 10px;
            color: var(--dark-color);
        }
        
        .result-box {
            background-color: #f8f9fa;
            border: 1px solid #ddd;
            border-radius: 4px;
            padding: 15px;
            max-height: 300px;
            overflow-y: auto;
            font-family: monospace;
            white-space: pre-wrap;
        }
        
        .vocab-list {
            max-height: 200px;
            overflow-y: auto;
            margin-top: 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            padding: 10px;
        }
        
        .vocab-item {
            padding: 5px;
            border-bottom: 1px solid #eee;
        }
        
        .vocab-item:last-child {
            border-bottom: none;
        }
        
        .vocab-index {
            display: inline-block;
            width: 25px;
            text-align: right;
            margin-right: 10px;
            color: var(--secondary-color);
            font-weight: bold;
        }
    </style>
</head>
<body>
    <header>
        <h1>未来之窗——文章向量化工具</h1>
        <p class="description">将文本转换为数值向量表示，支持自定义词汇添加，基于词袋模型(Bag of Words)实现</p>
    </header>
    
    <div class="container">
        <div class="card">
            <h2>文本处理</h2>
            <textarea id="textInput" placeholder="请输入要向量化的文本内容...">阿雪技术观
，未来之窗创始人，
在科技发展浪潮中，我们不妨积极投身技术共享。不满足于做受益者，更要主动担当贡献者。无论是分享代码、撰写技术博客，还是参与开源项目维护改进，每一个微小举动都可能蕴含推动技术进步的巨大能量。东方仙盟是汇聚力量的天地，我们携手在此探索硅基生命，为科技进步添砖加瓦
    
阿雪精通 28 门计算机语言，凭借其超凡的技术能力，成功开发过上万个应用，广泛涉及政府、商业、个人等众多领域，甚至在检察院、环保局、公安局等专业场景中也大放异彩。不仅熟练掌握单片机和物联网开发，在软件架构设计方面更是独树一帜，自创了跨平台软件</textarea>
            <div class="controls">
                <button id="vectorizeBtn">文本向量化</button>
                <button id="clearTextBtn" class="secondary">清空文本</button>
            </div>
            
            <div class="result-section">
                <h3>向量结果</h3>
                <div class="result-box" id="vectorResult"></div>
            </div>
        </div>
        
        <div class="card">
            <h2>词汇管理</h2>
            <div class="word-input-group">
                <input type="text" id="wordInput" placeholder="输入要添加的词汇...">
                <button id="addWordBtn" class="success">添加词汇</button>
            </div>
            <div class="controls">
                <button id="clearVocabBtn" class="secondary">清空词汇表</button>
                <button id="exportVocabBtn">导出词汇表(JSON)</button>
                <input type="file" id="importVocabBtn" accept=".json" style="display: none;">
                <button onclick="document.getElementById('importVocabBtn').click()">导入词汇表</button>
            </div>
            
            <div>
                <h3>当前词汇表 (<span id="vocabCount">0</span>)</h3>
                <div class="vocab-list" id="vocabList"></div>
            </div>
        </div>
    </div>

    <script>
        // 词汇表模块 Vocabulary
        const 未来之窗_词汇表 = (() => {
            class 未来之窗_词汇表 {
                constructor() {
                    this.words = {'未来之窗':0,'东方仙盟':1,'阿雪':2,'科技':3,'我们':4,'参与':5,'开源':6,'创始人':7};  // 词到索引的映射
                    this.index = 8;   // 当前索引值
                }
                
                /**
                 * 添加单词到词汇表
                 * @param {string} word - 要添加的单词
                 * @returns {boolean} - 如果添加成功返回true，否则返回false
                 */
                addWord(word) {
                    // 预处理：转为小写并去除空格
                    const processedWord = word.trim().toLowerCase();
                    
                    if (!processedWord) return false;
                    if (this.words[processedWord]) return false;
                    
                    this.words[processedWord] = this.index++;
                    return true;
                }
                
                /**
                 * 批量添加单词
                 * @param {string[]} words - 单词数组
                 */
                addWords(words) {
                    words.forEach(word => this.addWord(word));
                }
                
                /**
                 * 获取单词的索引
                 * @param {string} word - 单词
                 * @returns {number|null} - 索引值或null
                 */
                getWordIndex(word) {
                    const processedWord = word.trim().toLowerCase();
                    return this.words[processedWord] !== undefined ? this.words[processedWord] : null;
                }
                
                /**
                 * 获取词汇表大小
                 * @returns {number} - 词汇表大小
                 */
                getSize() {
                    return this.index;
                }
                
                /**
                 * 清空词汇表
                 */
                clear() {
                    this.words = {};
                    this.index = 0;
                }
                
                /**
                 * 导出词汇表为JSON
                 * @returns {string} - JSON字符串
                 */
                exportToJSON() {
                    return JSON.stringify({
                        words: this.words,
                        index: this.index
                    }, null, 2);
                }
                
                /**
                 * 从JSON导入词汇表
                 * @param {string} jsonStr - JSON字符串
                 * @returns {boolean} - 导入成功返回true
                 */
                importFromJSON(jsonStr) {
                    try {
                        const data = JSON.parse(jsonStr);
                        if (typeof data.words === 'object' && typeof data.index === 'number') {
                            this.words = data.words;
                            this.index = data.index;
                            return true;
                        }
                        return false;
                    } catch (e) {
                        console.error('导入词汇表失败:', e);
                        return false;
                    }
                }
                
                /**
                 * 获取所有单词
                 * @returns {string[]} - 单词数组
                 */
                getAllWords() {
                    return Object.keys(this.words);
                }
                
                /**
                 * 获取单词及其索引的映射
                 * @returns {Object} - 单词-索引映射对象
                 */
                getWordMap() {
                    return { ...this.words };
                }
            }
            
            return 未来之窗_词汇表;
        })();
        
        // 文本向量化模块 未来之窗_词汇表  
        const 未来之窗_文本向量化 = (() => {
            class 未来之窗_文本向量化 {
                /**
                 * 构造函数
                 * @param {Vocabulary} vocabulary - 词汇表实例
                 */
                constructor(v未来之窗_词汇表) {
                    if (!(v未来之窗_词汇表 instanceof 未来之窗_词汇表)) {
                        throw new Error('必须提供Vocabulary实例');
                    }
                    this.未来之窗_词汇表 = v未来之窗_词汇表;
                }
                
                /**
                 * 文本预处理
                 * @param {string} text - 原始文本
                 * @returns {string[]} - 处理后的单词数组
                 */
                preprocessText(text) {
                    // 转为小写
                    let processed = text.toLowerCase();
                    
                    // 移除特殊字符和标点
                    processed = processed.replace(/[^\w\s]/g, ' ');
                    
                    // 分词并过滤空字符串
                    return processed.split(/\s+/).filter(word => word.length > 0);
                }
                
                /**
                 * 将文本转换为向量
                 * @param {string} text - 输入文本
                 * @param {boolean} [updateVocab=true] - 是否更新词汇表
                 * @returns {number[]} - 文本向量
                 */
                vectorize(text, updateVocab = true) {
                    const words = this.preprocessText(text);
                    
                    // 如果需要，更新词汇表
                    if (updateVocab) {
                        this.未来之窗_词汇表.addWords(words);
                    }
                    
                    // 初始化向量
                    const vector = new Array(this.未来之窗_词汇表.getSize()).fill(0);
                    
                    // 计算词频
                    words.forEach(word => {
                        const index = this.未来之窗_词汇表.getWordIndex(word);
                        if (index !== null) {
                            vector[index]++;
                        }
                    });
                    
                    return vector;
                }
                
                /**
                 * 获取词汇表
                 * @returns {Vocabulary} - 词汇表实例
                 */
                getVocabulary() {
                    return this.未来之窗_词汇表;
                }
            }
            
            return 未来之窗_文本向量化;
        })();
        
        // 演示页面交互逻辑
        document.addEventListener('DOMContentLoaded', () => {
            // 初始化词汇表和向量化器
            const vocab = new 未来之窗_词汇表();
            const vectorizer = new 未来之窗_文本向量化(vocab);
            
            // DOM元素
            const textInput = document.getElementById('textInput');
            const vectorizeBtn = document.getElementById('vectorizeBtn');
            const clearTextBtn = document.getElementById('clearTextBtn');
            const vectorResult = document.getElementById('vectorResult');
            const wordInput = document.getElementById('wordInput');
            const addWordBtn = document.getElementById('addWordBtn');
            const clearVocabBtn = document.getElementById('clearVocabBtn');
            const exportVocabBtn = document.getElementById('exportVocabBtn');
            const importVocabBtn = document.getElementById('importVocabBtn');
            const vocabList = document.getElementById('vocabList');
            const vocabCount = document.getElementById('vocabCount');
            
            // 更新词汇表显示
            function updateVocabDisplay() {
                vocabList.innerHTML = '';
                const wordMap = vocab.getWordMap();
                
                // 按索引排序
                const sortedWords = Object.entries(wordMap).sort((a, b) => a[1] - b[1]);
                
                sortedWords.forEach(([word, index]) => {
                    const item = document.createElement('div');
                    item.className = 'vocab-item';
                    item.innerHTML = `<span class="vocab-index">${index}</span>${word}`;
                    vocabList.appendChild(item);
                });
                
                vocabCount.textContent = vocab.getSize();
            }
            
            // 文本向量化
            vectorizeBtn.addEventListener('click', () => {
                const text = textInput.value.trim();
                if (!text) {
                    alert('请输入文本内容');
                    return;
                }
                
                const vector = vectorizer.vectorize(text);
                vectorResult.textContent = JSON.stringify(vector, null, 2);
                updateVocabDisplay();
            });
            
            // 清空文本
            clearTextBtn.addEventListener('click', () => {
                textInput.value = '';
                vectorResult.textContent = '';
            });
            
            // 添加词汇
            addWordBtn.addEventListener('click', () => {
                const word = wordInput.value.trim();
                if (!word) {
                    alert('请输入要添加的词汇');
                    return;
                }
                
                const added = vocab.addWord(word);
                if (added) {
                    wordInput.value = '';
                    updateVocabDisplay();
                    alert(`词汇 "${word}" 已添加到词汇表`);
                } else {
                    alert(`词汇 "${word}" 已存在于词汇表中`);
                }
            });
            
            // 按Enter键添加词汇
            wordInput.addEventListener('keypress', (e) => {
                if (e.key === 'Enter') {
                    addWordBtn.click();
                }
            });
            
            // 清空词汇表
            clearVocabBtn.addEventListener('click', () => {
                if (confirm('确定要清空词汇表吗？这将删除所有已添加的词汇。')) {
                    vocab.clear();
                    vectorResult.textContent = '';
                    updateVocabDisplay();
                }
            });
            
            // 导出词汇表
            exportVocabBtn.addEventListener('click', () => {
                if (vocab.getSize() === 0) {
                    alert('词汇表为空，无需导出');
                    return;
                }
                
                const jsonStr = vocab.exportToJSON();
                const blob = new Blob([jsonStr], { type: 'application/json' });
                const url = URL.createObjectURL(blob);
                
                const a = document.createElement('a');
                a.href = url;
                a.download = 'vocabulary_' + new Date().getTime() + '.json';
                document.body.appendChild(a);
                a.click();
                
                // 清理
                setTimeout(() => {
                    document.body.removeChild(a);
                    URL.revokeObjectURL(url);
                }, 0);
            });
            
            // 导入词汇表
            importVocabBtn.addEventListener('change', (e) => {
                const file = e.target.files[0];
                if (!file) return;
                
                const reader = new FileReader();
                reader.onload = (event) => {
                    const content = event.target.result;
                    const success = vocab.importFromJSON(content);
                    
                    if (success) {
                        updateVocabDisplay();
                        alert('词汇表导入成功');
                    } else {
                        alert('词汇表导入失败，请检查文件格式');
                    }
                };
                reader.readAsText(file);
                
                // 重置输入，允许重复选择同一文件
                e.target.value = '';
            });
            
            // 初始化显示
            updateVocabDisplay();
        });
    </script>
</body>
</html>
